/**
 * WebSocket客户端工具
 * 用于连接后端WebSocket服务并接收实时通知
 */
class WebSocketClient {
  constructor() {
    this.ws = null
    this.url = null
    this.token = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectDelay = 3000
    this.messageHandlers = []
    this.isConnecting = false
    this.isConnected = false
  }

  /**
   * 连接WebSocket服务器
   * @param {string} token - JWT Token
   */
  connect(token) {
    // 如果已经连接且token相同，直接返回
    if (this.isConnected && this.token === token) {
      console.log('WebSocket already connected with same token')
      return
    }
    
    // 如果正在连接，等待连接完成
    if (this.isConnecting) {
      console.log('WebSocket already connecting')
      return
    }
    
    // 如果token改变，断开旧连接
    if (this.isConnected && this.token !== token) {
      console.log('Token changed, disconnecting old connection')
      this.disconnect()
    }

    this.token = token
    // 从localStorage获取baseURL，默认使用localhost:8000
    const baseURL = localStorage.getItem('apiBaseURL') || 'http://localhost:8000'
    // 将http://转换为ws://，https://转换为wss://
    const wsBaseURL = baseURL.replace(/^http/, 'ws')
    this.url = `${wsBaseURL}/ws/${token}`

    this.isConnecting = true
    this.connectInternal()
  }

  connectInternal() {
    try {
      console.log('Connecting to WebSocket:', this.url)
      this.ws = new WebSocket(this.url)

      this.ws.onopen = () => {
        console.log('WebSocket connected')
        this.isConnected = true
        this.isConnecting = false
        this.reconnectAttempts = 0
        
        // 触发连接成功事件
        this.notifyHandlers({ type: 'connected' })
      }

      this.ws.onmessage = (event) => {
        try {
          const message = JSON.parse(event.data)
          console.log('WebSocket message received:', message)
          
          // 触发消息处理
          this.notifyHandlers({ type: 'message', data: message })
        } catch (error) {
          console.error('Failed to parse WebSocket message:', error)
        }
      }

      this.ws.onerror = (error) => {
        console.error('WebSocket error:', error)
        this.isConnecting = false
      }

      this.ws.onclose = () => {
        console.log('WebSocket closed')
        this.isConnected = false
        this.isConnecting = false
        
        // 触发断开连接事件
        this.notifyHandlers({ type: 'disconnected' })
        
        // 尝试重连
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
          this.reconnectAttempts++
          console.log(`Reconnecting... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
          setTimeout(() => {
            if (!this.isConnected) {
              this.connectInternal()
            }
          }, this.reconnectDelay)
        } else {
          console.error('Max reconnection attempts reached')
          this.notifyHandlers({ type: 'reconnect_failed' })
        }
      }
    } catch (error) {
      console.error('Failed to create WebSocket connection:', error)
      this.isConnecting = false
      this.notifyHandlers({ type: 'error', error })
    }
  }

  /**
   * 断开WebSocket连接
   */
  disconnect() {
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    this.isConnected = false
    this.isConnecting = false
    this.reconnectAttempts = 0
  }

  /**
   * 添加消息处理器
   * @param {Function} handler - 消息处理函数
   */
  onMessage(handler) {
    if (typeof handler === 'function') {
      this.messageHandlers.push(handler)
    }
  }

  /**
   * 移除消息处理器
   * @param {Function} handler - 要移除的处理函数
   */
  offMessage(handler) {
    const index = this.messageHandlers.indexOf(handler)
    if (index > -1) {
      this.messageHandlers.splice(index, 1)
    }
  }

  /**
   * 通知所有处理器
   * @param {Object} event - 事件对象
   */
  notifyHandlers(event) {
    this.messageHandlers.forEach(handler => {
      try {
        handler(event)
      } catch (error) {
        console.error('Error in message handler:', error)
      }
    })
  }

  /**
   * 发送消息到服务器
   * @param {Object} data - 要发送的数据
   */
  send(data) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data))
    } else {
      console.warn('WebSocket is not connected')
    }
  }
}

// 创建单例
const wsClient = new WebSocketClient()

export default wsClient

